package com.platform.mall.security.filter;

import com.platform.mall.security.userdetails.member.MemberUserDetails;
import com.platform.mall.security.userdetails.member.UserMemberDetailsServiceImpl;
import com.platform.mall.security.userdetails.user.SysUserDetails;
import com.platform.mall.security.userdetails.user.SysUserDetailsServiceImpl;
import com.platform.mall.utils.JWTokenUtil;
import lombok.AllArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * JWT Filter
 *
 * @author xuwang
 * Created on 2019/05/29 16:10.
 */
@Component
@AllArgsConstructor
public class PLAuthenticationTokenFilter extends OncePerRequestFilter {

    private final SysUserDetailsServiceImpl userDetailsService;
    private final UserMemberDetailsServiceImpl memberDetailsService;
    private final JWTokenUtil jwTokenUtil;


    /**
     * 获取验证token中的身份信息
     *
     * @author xuwang
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        //从请求头中获取token
        String authHeader = request.getHeader("Authorization");
        //token前缀
        String tokenHead = "Bearer ";
        if (authHeader != null && authHeader.startsWith(tokenHead)) {
            //去掉token前缀
            String authToken = authHeader.substring(tokenHead.length());
            //从token中获取用户名
            String username = jwTokenUtil.getUsernameFromToken(authToken);
            String userType = jwTokenUtil.getUserTypeFromToken(authToken);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = null;
                String grantType = request.getHeader("grant_type");
                Assert.notNull(grantType,"授权类型不能为null");
                if (userType.equals(MemberUserDetails.USER_TYPE)) {
                    if ("sms_code".equals(grantType)) {
                        userDetails = memberDetailsService.loadUserByMobile(username);
                    } else if ("wechat".equals(grantType)) {
                        userDetails = memberDetailsService.loadUserByOpenId(username);
                    }
                } else if (userType.equals(SysUserDetails.USER_TYPE)) {
                    userDetails = userDetailsService.loadUserByUsername(username);
                }
                if (jwTokenUtil.validateToken(authToken, userDetails)) {
                    //token中的用户信息和数据库中的用户信息对比成功后将用户信息加入SecurityContextHolder相当于登陆
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);
    }

}